package com.demo2do.fms.admin.visitor.impl;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.demo2do.fms.admin.service.DataService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.demo2do.fms.admin.service.GenericDataService;
import com.demo2do.fms.admin.service.business.BalanceService;
import com.demo2do.fms.admin.service.business.DispatchOrderService;
import com.demo2do.fms.admin.service.business.ShipmentService;
import com.demo2do.fms.admin.service.data.MasterDataService;
import com.demo2do.fms.admin.service.supplier.DriverService;
import com.demo2do.fms.admin.service.supplier.SupplierService;
import com.demo2do.fms.admin.service.supplier.VehicleSourceService;
import com.demo2do.fms.entity.authority.Branch;
import com.demo2do.fms.entity.authority.Organization;
import com.demo2do.fms.entity.authority.User;
import com.demo2do.fms.entity.business.Shipment;
import com.demo2do.fms.entity.business.balance.Order;
import com.demo2do.fms.entity.business.out.Consignor;
import com.demo2do.fms.entity.business.shipment.DispatchOrder;
import com.demo2do.fms.entity.business.shipment.TransportCost;
import com.demo2do.fms.entity.data.business.Client;
import com.demo2do.fms.entity.data.business.LoadPlace;
import com.demo2do.fms.entity.data.business.Warehouse;
import com.demo2do.fms.entity.data.car.CarCategory;
import com.demo2do.fms.entity.data.car.CarColor;
import com.demo2do.fms.entity.data.car.CarType;
import com.demo2do.fms.entity.data.car.Manufacturer;
import com.demo2do.fms.entity.driver.Driver;
import com.demo2do.fms.entity.driver.DriverAuditStatus;
import com.demo2do.fms.entity.driver.Employee;
import com.demo2do.fms.entity.driver.Team;
import com.demo2do.fms.entity.supplier.common.AuditStatus;
import com.demo2do.fms.entity.supplier.common.Supplier;
import com.demo2do.fms.entity.supplier.common.SupplierEvent;
import com.demo2do.fms.entity.supplier.common.SupplierEventType;
import com.demo2do.fms.entity.supplier.common.Type;
import com.demo2do.fms.entity.vehicle.source.Vehicle;
import com.demo2do.fms.entity.vehicle.source.VehicleGpsInfo;
import com.demo2do.fms.entity.vehicle.tractor.Tractor;
import com.demo2do.fms.entity.vehicle.trailer.Trailer;

/**
 * @author Ysy
 */
@Component("persistentVisitor")
public class PersistentVisitor {

    @Autowired
    private MasterDataService masterDataService;
    
    @Autowired
    private GenericDataService genericDataService;
    
    @Autowired
    private ShipmentService shipmentService;
    
    @Autowired
    private DispatchOrderService dispatchOrderService;
    
    @Autowired
    private BalanceService balanceService;
    
    @Autowired 
    private DriverService driverService;
    
    @Autowired
    private VehicleSourceService vehicleSourceService;
    
    @Autowired
    private SupplierService supplierService;

    @Qualifier("dataService")
    @Autowired
    private DataService dataService;
    
    /**
     * @param driverId
     * @return
     */
    public Driver driver(Long driverId) {
        return genericDataService.load(Driver.class, driverId);
    }
    
    /**
     * 
     * @param targets
     * @return
     */
    public String realTargets(String targets) {
    	return targets.replace(",", "、");
    }
    
    /**
     * 
     * @param supplierId
     * @return
     */
    public List<Driver> drivers(Long supplierId) {
        
        if (supplierId == null) {
            return null;
        }
        
        return driverService.list(supplierId, DriverAuditStatus.QUALIFIED);
        
    }
    
    /**
     * 
     * @return
     */
    public List<Driver> getDrivers() {
        return driverService.list(DriverAuditStatus.QUALIFIED);
    }
    
    /**
     * @param vehicleCode
     * @return
     */
    public Integer getDriverAmount(String vehicleCode) {
    	
    	List<Driver> drivers = driverService.list(vehicleCode, DriverAuditStatus.QUALIFIED);
    	if (CollectionUtils.isEmpty(drivers)) {
    		return null;
    	}
    	
    	return drivers.size();
    	
    }
    
    /**
     * @param oilTypeId
     * @return
     */
    public String oilType(Long oilTypeId) {
        
        if (oilTypeId == null) {
            return null;
        }
        
        return masterDataService.getOilType(oilTypeId);
        
    }
    
    /**
     * get master_data by type and id
     * 
     * @param type
     * @param id
     * @return
     */
    public String masterData(String type, Long id) {
    	
    	if (new Long(-1).equals(id)) {
    		return null;
    	}
    	
        return masterDataService.load(type, id);
        
    }
    
    /**
     * @param id
     * @return
     */
    public Vehicle vehicle(Long id) {
        return genericDataService.load(Vehicle.class, id);
    }

    /**
     * 
     * @param code
     * @return
     */
    public VehicleGpsInfo vehicleGpsInfo(String code) {
        
        // 0. validate code
        if (StringUtils.isEmpty(code)) {
            return null;
        }
    	
    	// 1. load vehicle by code
    	Vehicle vehicle = genericDataService.load(Vehicle.class, code);
    	if (vehicle == null) {
    		return null;
    	}
    	
    	// 2. load gps info by vehicleId
    	VehicleGpsInfo info = vehicleSourceService.loadVehicleGpsInfo(vehicle.getId());
    	return info;
    	
    }

    /**
     * @param id
     * @return
     */
    public Warehouse warehouse(Long id) {
        return genericDataService.load(Warehouse.class, id);
    }

    /**
     * @param id
     * @return
     */
    public Client client(Long id) {
        return genericDataService.load(Client.class, id);
    }

    /**
     * @param id
     * @return
     */
    public Manufacturer manufacturer(Long id) {
        return genericDataService.load(Manufacturer.class, id);

    }

    /**
     * @param id
     * @return
     */
    public Organization organization(Long id) {
        return genericDataService.load(Organization.class, id);
    }

    /**
     * @param id
     * @return
     */
    public LoadPlace loadPlace(Long id) {
        return genericDataService.load(LoadPlace.class, id);
    }
    
    /**
     * 
     * @param id
     * @return
     */
    public Employee employee(Long id){
        return genericDataService.load(Employee.class, id);
    }
    
    /**
     * 
     * @param id
     * @return
     */
    public Consignor consignor(Long id){
        return genericDataService.load(Consignor.class, id);
    }
    
	/**
	 * 
	 * @param id
	 * @return
	 */
	public CarType carType(Long id) {
		return genericDataService.load(CarType.class, id);
	}

	/**
	 * @param id
	 * @return
	 */
	public CarColor carColor(Long id) {
		return genericDataService.load(CarColor.class, id);
	}
	
	/**
	 * @param id
	 * @return
	 */
	public CarCategory carCategory(Long id) {
	    return genericDataService.load(CarCategory.class, id);
	}
   
	/**
	 * 
	 * @param id
	 * @return
	 */
	public User user(Long id) {
		return genericDataService.load(User.class, id);
	}
   
	/**
	 * @param id
	 * @return
	 */
	public Supplier supplier(Long id) {
		return genericDataService.load(Supplier.class, id);
	}
	
	/**
	 * @return
	 */
	public List<Supplier> transSuppliers() {
	    List<AuditStatus> status = Arrays.asList(AuditStatus.QUALIFIED, AuditStatus.ONE_LEVEL_RECTIFY, AuditStatus.TWO_LEVEL_RECTIFY, AuditStatus.UNITE_RECTIFY);
        List<Supplier> suppliers = supplierService.list(Type.MOTOR, status);
        return suppliers;
	}

	/**
	 * @param supplier
	 * @return
	 */
	public List<Supplier> parentSupplier(Supplier supplier) {
		return supplierService.listParentSupplier(supplier);
	}
	
	public String prettyParentSupplier(Supplier supplier) {
	    
	    StringBuilder stringBuilder = new StringBuilder();
	    
	    List<Supplier> suppliers = this.parentSupplier(supplier);
	    
	    for (Supplier inner : suppliers) {
	        stringBuilder.append(inner.getCode());
	        stringBuilder.append("-");
	        stringBuilder.append(inner.getName());
	        stringBuilder.append("  ");
        }
	    
	    return stringBuilder.toString();
	}
   
    /**
     * @param code
     * @return
     */
    public Branch branch(String code){
        return code.isEmpty() ? null : genericDataService.load(Branch.class, code);
    }
    
    /**
     * @param dispatchOrderId
     * @return
     */
    public DispatchOrder dispatchOrder(Long dispatchOrderId) {
        return dispatchOrderService.loadDispatchOrder(dispatchOrderId);
    }
    
    /**
     * @param orderId
     * @return
     */
    public Order order(Long orderId) {
        return genericDataService.load(Order.class, orderId);
    }
   
    /**
     * @param dispatchOrderId
     * @return
     */
    public TransportCost transportCost(Long dispatchOrderId) {
        return dispatchOrderService.getTransportCost(dispatchOrderId);
    }
    
    /**
     * @param teamId
     * @return
     */
    public Team team(Long teamId) {
        return genericDataService.load(Team.class, teamId);
    }
   
    /**
     * @param dispatchOrderId
     * @return
     */
    public Object otherFee(Long dispatchOrderId) {
        return dispatchOrderService.getOtherFee(dispatchOrderId);
    }
    
    /**
     * @param dispatchOrderId
     * @param otherFeeTypeId
     * @return
     */
    public Object otherFeeDetail(Long dispatchOrderId, Long otherFeeTypeId) {
    	return dispatchOrderService.getOtherFeeDetail(dispatchOrderId, otherFeeTypeId);
    }
    
    /**
     * 获取派车单中商品车详情
     * 
     * @param dispatchOrderId
     * @return
     */
    public String carSummary(Long dispatchOrderId) {
    	return dispatchOrderService.getCarSummary(dispatchOrderId);
    }
    
    /**
     * 订单状态
     * 
     * @param financeId
     * @param shipmentFinanceId
     * @return
     */
    public int orderStatus(Long financeId, Long shipmentFinanceId) {
        return balanceService.getOrderStatus(financeId, shipmentFinanceId);
    }
    
    /**
     * 
     * @param shipmentId
     * @return
     */
    public String vinCode(Long shipmentId) {
        Shipment shipment = shipmentService.loadShipment(shipmentId);
        return shipment == null ? null : shipment.getVinCode();
    }
    
    /**
     * 
     * @param supplierId
     * @return
     */
    public SupplierEvent supplierRejectEvent(Long supplierId) {
        return supplierService.getSupplierEvent(supplierId, SupplierEventType.INTRODUCE_REJECTED);
    }
    
    /**
     * 
     * @param supplierId
     * @return
     */
    public SupplierEvent supplierChangingRejectEvent(Long supplierId) {
        return supplierService.getSupplierEvent(supplierId, SupplierEventType.CHANGE_REJECTED);
    }
    
    /**
     * @param tractorId
     * @return
     */
    public Tractor tractor(Long tractorId) {
        return genericDataService.load(Tractor.class, tractorId);
    }
    
    /**
     * @param trailerId
     * @return
     */
    public Trailer trailer(Long trailerId) {
        return genericDataService.load(Trailer.class, trailerId);
    }

    public List<Branch> listAllBranch(){
        return dataService.listAll(Branch.class);
    }

    /**
     * 获取一般存储服务供方审核状态枚举
     * @return
     */
    public List<AuditStatus> getCommonStorageSupplierAuditStatusEnums(){

        AuditStatus[] auditStatuses = AuditStatus.values();

        List<AuditStatus> collect = Arrays.stream(auditStatuses).filter(e -> e.canCommonStotageSupplierShow()).collect(Collectors.toList());

        return collect;
    }
}
